#include <iostream>
#include <memory>
#include <cassert>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "HttpServer.hpp"
#include "Usage.hpp"
#include "Util.hpp"

// 一般http都要有自己的web根目录
#define ROOT "./wwwroot" // ./wwwroot/index.html
// 如果客户端只请求了一个/,我们返回默认首页
#define HOMEPAGE "index.html"

/**
 * @brief 处理HTTP请求的回调函数
 *
 * @param sockfd 已连接的套接字描述符，用于与客户端通信
 */
void HandlerHttpRequest(int sockfd)
{
    // 1. 读取请求 for test
    char buffer[10240]; // 缓冲区，用于暂存接收到的HTTP请求数据
    ssize_t s = recv(sockfd, buffer, sizeof(buffer) - 1, 0); // 接收请求数据
    if (s > 0)
    {
        buffer[s] = 0; // 添加终止符，便于后续字符串操作
    }
    std::cout << buffer << "\n--------------------\n" << std::endl;

    std::vector<std::string> vline; // 用于存储请求数据按行分割后的结果
    Util::cutString(buffer, "\n", &vline); // 按换行符分割请求数据

    std::vector<std::string> vblock; // 用于存储请求行按空格分割后的结果
    Util::cutString(vline[0], " ", &vblock); // 按空格分割请求行

    std::string file = vblock[1]; // 请求的文件路径（如 /index.html）
    std::string target = ROOT; // 实际要访问的文件路径（基于Web根目录）

    if(file == "/") file = "/index.html"; // 若请求路径为 /，则替换为默认首页
    target += file; // 拼接实际文件路径
    std::cout << target << std::endl; // 输出实际文件路径（调试用）

    std::string content; // 存储读取到的文件内容
    std::ifstream in(target); // 打开目标文件
    if(in.is_open())
    {
        std::string line;
        while(std::getline(in, line))
        {
            content += line;
        }
        in.close(); // 关闭文件
    }

    std::string HttpResponse; // 存储待发送的HTTP响应
    if(content.empty()) // 若文件未找到或读取失败
    {
        HttpResponse = "HTTP/1.1 404 NotFound\r\n"; // 构建404响应状态码和消息
    }
    else
    {
        HttpResponse = "HTTP/1.1 200 OK\r\n"; // 构建200响应状态码和消息
        HttpResponse += "Content-Type: text/html\r\n";
        HttpResponse += "Content-Length: " + std::to_string(content.size()) + "\r\n";
        HttpResponse += "Set-Cookie: 这是一个cookie\r\n";
    }
    HttpResponse += "\r\n"; // 添加空行分隔状态行与响应体
    HttpResponse += content; // 追加文件内容至响应体
    // 下面的注释代码已省略，用于调试输出请求行字段

    // 发送HTTP响应至客户端
    send(sockfd, HttpResponse.c_str(), HttpResponse.size(), 0);
}

int main(int argc, char *argv[])
{
    if (argc != 2) // 检查命令行参数数量
    {
        Usage(argv[0]); // 参数不足时打印使用说明
        exit(0); // 退出程序
    }

    // 创建并启动HTTP服务器
    std::unique_ptr<HttpServer> httpserver(new HttpServer(atoi(argv[1]), HandlerHttpRequest)); // 创建HttpServer对象，传入端口号和请求处理器
    httpserver->Start(); // 启动服务器

    return 0; // 程序正常结束
}